#pragma once
#include "Config.h"

struct LineEq {
	CVector<float> C;
	float zStart;
	float zEnd;

	bool isValid() const { return !C.empty(); }
	//bool operator==(const LineEq& other) const { return C == other.C && zStart == other.zStart && zEnd == other.zEnd; }
	//bool operator!=(const LineEq& other) const { return !(*this == other); }

	enum Side { None, Left, Right, Tripple_Left, Tripple_Right };
	LineEq sideEq(Side side) const {
		auto eq = *this;
		if (side == Side::None)
			return eq;
		const auto HInterval = Config::Line_HInterval;
		float deltaC0 = 0;
		if (side == Side::Left || side == Side::Right)// double line
			deltaC0 = Config::Line_Width / 2 + HInterval / 2;
		else if (side == Side::Tripple_Left || side == Side::Tripple_Right)// tripple line
			deltaC0 = Config::Line_Width + HInterval;
		deltaC0 *= ((side == Side::Left || side == Side::Tripple_Left) ? 1 : -1);// left direction is positive
		eq.C[0] += deltaC0;
		return eq;
	}
};

/***********************************************************************/
/***********************************************************************/
struct LineArg {
	LineTag tag;
	LineEq eq;
	LineStyle style;
	CColor color = Config::Line_DefColor;
	bool isCrossing = false;// is crossing lane line
	int probability = 100;// Target probability: 0 ~ 100
	bool identified = true;
	int updateCnt = -1;
	int updateFrameCnt = -1;

	bool isValid() const { return updateCnt != -1; }
};

/** @warning default boolean value should be set, otherwise, a random value may be setted! */
struct ModelArg {
	int ID;
	ModelType type;
	P pos;
	float angle = 0;// Unit: radians
	bool isOncoming = false;
	bool isAccTracking = false;
	CColor color;
	MoveStatus moveStatus;
	int probability = 100;// Target probability: 0 ~ 100
	float width = 0;// Unit: m
	float length = 0;// Unit: m
	P2D relSpeed = P2D(0);// Relatively close:negative, relatively far away:positive;Unit: m/s
	bool identified = true;
	int updateCnt = -1;
	int updateFrameCnt = -1;

	bool isValid() const { return updateCnt != -1; }
};

struct ZhicheArg {
	P pos = P(0);
	float angle = 0;// Unit: radians
	float speed = 0;// Unit: km/h
	float width = 0;// Unit: m
	float length = 0;// Unit: m

	bool isValid() const { return width > 0 && length > 0; }
};

/** @note Status: not associated with LineArg and ModleArg directly*/
struct Status {
	DCLC dclc = DCLC::Invalid;//Config::TestCase_HideDclcArrow ? DCLC::None : DCLC::Mid;
	ALC alc = ALC::Invalid;
	LDW ldw = LDW::Invalid;
	ACC_TG accTG = ACC_TG::Invalid;
	TailLamp tailLamp = TailLamp::Invalid;
};

/*******************Project SQ*************************/
/******************************************************/
namespace sq {
	struct ModelArg {
		int id;
		ModelType type;
		P pos;
		float angle;// Unit: degrees
	};

	struct LineArg {
		LineTag tag;
		LineEq eq;
		LineStyle style;
		CColor color = Config::Line_DefColor;
		int reserve = 0;
	};

	struct Status {
	    sq::ACC acc = sq::ACC::Invalid;
	    sq::FCW fcw = sq::FCW::Invalid;
	    sq::ALC alc = sq::ALC::Invalid;
	    sq::ACAS acas = sq::ACAS::Invalid;
		sq::NOA noa = sq::NOA::Invalid;
	};
}